unit uFile ;

interface

uses
    SysUtils,
    Classes,
    ActnList,
    ImgList,
    Controls,
    TntDialogs,
    Dialogs,
    TB2MRU,
    TBXExtItems,

    SciLexer,
    SciLexerMemo,
    SciLexerMod,
    SciFileExtensionsManager,
    SciLexerOptionsDlg,
    sciPrint ;

type
    TdmFile = class( TDataModule )
        ActionList : TActionList ;
        actSave : TAction ;
        actOpen : TAction ;
        actNew : TAction ;
        actSaveAs : TAction ;
        MRUList : TTBXMRUList ;
        TntOpenDialog : TTntOpenDialog ;
        TntSaveDialog : TTntSaveDialog ;
        actOptions : TAction ;
        dlgSCOptions : TScintillaOptionsDlg ;
        printScintilla : TSciPrinter ;
        actPrint : TAction ;
        procedure actOpenExecute( Sender : TObject ) ;
        procedure DataModuleCreate( Sender : TObject ) ;
        procedure actOptionsExecute( Sender : TObject ) ;
        procedure actOptionsUpdate( Sender : TObject ) ;
        procedure actPrintExecute( Sender : TObject ) ;
        procedure actSaveExecute( Sender : TObject ) ;
        procedure actSaveAsExecute( Sender : TObject ) ;
        procedure actNewExecute( Sender : TObject ) ;
        procedure actSaveUpdate( Sender : TObject ) ;
        procedure actSaveAsUpdate( Sender : TObject ) ;
        procedure actPrintUpdate( Sender : TObject ) ;
        procedure actNewUpdate( Sender : TObject ) ;
        procedure actOpenUpdate( Sender : TObject ) ;
        procedure MRUListClick( Sender : TObject ; const Filename : string ) ;
        procedure DataModuleDestroy( Sender : TObject ) ;
    private
        { Private declarations }
        fEditor : TScintilla ;
        fFilename : string ;
        fExtMapper : TExtensionMapper ;
        procedure SetEditor( const Value : TScintilla ) ;
        function DoUpdate : boolean ;
        procedure DetectHighlighter( Sender : TObject ; const Extension : string ;
            var Language : string ) ;
    public
        { Public declarations }
        property Editor : TScintilla read FEditor write SetEditor ;
    end ;

var
    dmFile          : TdmFile ;

implementation

{$R *.dfm}

procedure TdmFile.DataModuleCreate( Sender : TObject ) ;
var
    iExt, iLang, iFilter : string ;
    i               : integer ;
begin
    fExtMapper := TExtensionMapper.Create ;
    with fExtMapper do begin
        Add( '.xml;.mtx;.sch;.pcb', 'XML' ) ;
        Add( '.vhd;.vhi;.vhdl', 'VHDL' ) ;
        Add( '.py;.pyw', 'Python' ) ;
        Add( '.*', 'All files' ) ;
        for i := 0 to ExtensionsList.Count - 1 do begin
            iLang := ExtensionsList.Items[ i ].Language ;
            iExt := ExtensionsList.Items[ i ].Extensions ;
            iExt := StringReplace( iExt, '.', '*.', [ rfReplaceAll ] ) ;
            if i = 0 then
                iFilter := Format( '%s files (%s)|%s', [ iLang, iExt, iExt ] )
            else
                iFilter := iFilter + '|' + Format( '%s files (%s)|%s', [ iLang, iExt, iExt ] ) ;
        end ;
    end ;
    fFilename := 'Untitled' ;
    TNTOpenDialog.Filter := iFilter ;
    TNTSaveDialog.Filter := TNTOpenDialog.Filter ;
end ;

procedure TdmFile.DataModuleDestroy( Sender : TObject ) ;
begin
    Editor := nil ;
    fExtMapper.Free ;
end ;

function TdmFile.DoUpdate : boolean ;
begin
    Result := True ;
    if fEditor.Modified then begin
        case MessageDlg( Format( 'Save: %s?', [ fFilename ] ), mtInformation, [ mbYes, mbNo, mbCancel ], 0 ) of
            mrNo : Exit ;
            mrCancel : Result := False ;
        end ;
        if Result then
            with TNTSaveDialog do begin
                Filename := fFilename ;
                if Execute then begin
                    fFilename := Filename ;
                    fEditor.SaveToFile( Filename ) ;
                    MRUList.Add( Filename ) ;
                end ;
            end ;
    end ;
end ;

procedure TdmFile.actNewExecute( Sender : TObject ) ;
begin
    if assigned( fEditor ) and DoUpdate then begin
        fEditor.ClearAll ;
        fEditor.Modified := False ;
    end ;
end ;

procedure TdmFile.actNewUpdate( Sender : TObject ) ;
begin
    actNew.Enabled := assigned( fEditor ) ;
end ;

procedure TdmFile.MRUListClick( Sender : TObject ; const Filename : string ) ;
begin
    if assigned( fEditor ) then
        fEditor.LoadFromFile( Filename ) ;
end ;

procedure TdmFile.actOpenExecute( Sender : TObject ) ;
var
    ext, lang       : string ;
begin
    if assigned( fEditor ) and DoUpdate then
        with TNTOpenDialog do begin
            Filename := fFilename ;
            if Execute then begin
                fFilename := Filename ;
                ext := ExtractFileExt( Filename ) ;
                DetectHighlighter( Sender, ext, lang ) ;
                fEditor.LoadFromFile( Filename ) ;
                fEditor.LanguageManager.SelectedLanguage := lang ;
                MRUList.Add( Filename ) ;
            end ;
        end ;
end ;

procedure TdmFile.actOpenUpdate( Sender : TObject ) ;
begin
    actOpen.Enabled := assigned( fEditor ) ;
end ;

procedure TdmFile.actSaveExecute( Sender : TObject ) ;
begin
    if assigned( fEditor ) then begin
        if fFilename = 'Untitled' then
            actSaveAsExecute( Sender )
        else
            fEditor.SaveToFile( fFilename ) ;
    end ;
end ;

procedure TdmFile.actSaveUpdate( Sender : TObject ) ;
begin
    actSave.Enabled := assigned( fEditor ) and fEditor.Modified ;
end ;

procedure TdmFile.actSaveAsExecute( Sender : TObject ) ;
var
    ext, lang       : string ;
begin
    if assigned( fEditor ) then
        with TNTSaveDialog do begin
            Filename := fFilename ;
            if Execute then begin
                fFilename := Filename ;
                fEditor.SaveToFile( Filename ) ;
                ext := ExtractFileExt( Filename ) ;
                DetectHighlighter( Sender, ext, lang ) ;
                fEditor.LanguageManager.SelectedLanguage := lang ;
                MRUList.Add( Filename ) ;
            end ;
        end ;
end ;

procedure TdmFile.actSaveAsUpdate( Sender : TObject ) ;
begin
    actSaveAs.Enabled := assigned( fEditor ) ;
end ;

procedure TdmFile.DetectHighlighter( Sender : TObject ; const Extension : string ; var Language : string ) ;
begin
    Language := fExtMapper.DetectLanguage( Extension ) ;
end ;

procedure TdmFile.actOptionsExecute( Sender : TObject ) ;
begin
    if assigned( dlgSCOptions.Editor ) then
        with dlgSCOptions do
            if Execute then
end ;

procedure TdmFile.actOptionsUpdate( Sender : TObject ) ;
begin
    actOptions.Enabled := assigned( Editor ) ;
end ;

procedure TdmFile.actPrintExecute( Sender : TObject ) ;
begin
    if assigned( printScintilla.Editor ) then
        printScintilla.Print ;
end ;

procedure TdmFile.actPrintUpdate( Sender : TObject ) ;
begin
    actPrint.Enabled := assigned( Editor ) ;
end ;

procedure TdmFile.SetEditor( const Value : TScintilla ) ;
begin
    fEditor := Value ;
    printScintilla.Editor := Value ;
    dlgSCOptions.Editor := Value ;
end ;

initialization
    dmFile := TdmFile.Create( nil ) ;

finalization
    dmFile.Free ;

end.

